home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 8614 / 8614.xpi / chrome / extension.jar / content / ui / recommendations / DetachedPopupsManager.js next >
Encoding:
Text File  |  2010-02-10  |  10.8 KB  |  353 lines

  1. Glydo.DetachedPopupsManager = Prototype.Class.create(Glydo.EventSource,{
  2.  
  3.     initialize: function($super,application) {
  4.         $super();
  5.         this.openedPopup = null;
  6.         this.detachedWindows = {};
  7.         this.application = application;
  8.         this.panel = document.getElementById("glydo-recommendations-popup");
  9.         this.panelTitle = document.getElementById("glydo-vertical-pane-title")
  10.         this.panelRecommendationsView = document.getElementById("glydo-recpopup-recommendations-view");
  11.         this.onPanelHoverEnter = Prototype.F.bindAsEventListener(Prototype.F.curry(this.onPanelHover,true),this);
  12.         this.onPanelHoverExit = Prototype.F.bindAsEventListener(Prototype.F.curry(this.onPanelHover,false),this);
  13.     },
  14.  
  15.     openDetachedWindow: function(defs,options) {
  16.         // If a detached window with this name is already open, bring it to focus
  17.         var win = this.detachedWindows[defs.name];
  18.         if (win) {
  19.             win.focus();
  20.             return;
  21.         }
  22.     
  23.         var features = "chrome,dialog=no,titlebar=no,close=no,alwaysRaised=yes";
  24.         if  (Glydo.Utils.platformShort() == 'mac') {
  25.             features = "dialog=no, chrome, resizable=no,dependent=yes";
  26.         }
  27.         
  28.         var screenX = options.anchor.boxObject.screenX + options.anchor.boxObject.width - 250 - 1 - 30;
  29.         var screenY = options.anchor.boxObject.screenY - 3 - 384 - 30;
  30.         if (options.from_popup) {
  31.             screenX = options.from_popup.boxObject.x - 30;
  32.             screenY = options.from_popup.boxObject.y - 30;
  33.         }
  34.         
  35.         features += ",top=" + screenY + ",left=" + screenX;
  36.         
  37.         win = window.openDialog("chrome://glydo/content/ui/recommendations/vertical_pane_xul/vertical_pane_window.xul", 
  38.                           "_blank", 
  39.                           features,
  40.                           this.application,
  41.                           defs.filter,
  42.                           defs.title,
  43.                           defs.name);
  44.         Glydo.Utils.addListener(win,"load", Prototype.F.curry(this.onWindowLoaded,defs.name), this, false);
  45.         this.detachedWindows[defs.name] = win;
  46.     },
  47.  
  48.     closeDetachedWindow: function(name) {
  49.         var win = this.detachedWindows[name];
  50.         if (!win) {
  51.             return false;
  52.         }
  53.         win.close();
  54.         return true;
  55.     },
  56.  
  57.     toggleDetachedWindow: function(defs,options) {
  58.         var win = this.detachedWindows[defs.name];
  59.         if (win) {
  60.             this.closeDetachedWindow(defs.name);
  61.         } else {
  62.             this.openDetachedWindow(defs,options);
  63.         }
  64.     },
  65.  
  66.     toggleDetachedWindowAndHidePopup: function(defs,options) {
  67.         var win = this.detachedWindows[defs.name];
  68.         if (win) {
  69.             this.closeDetachedWindow(defs.name);
  70.         } else {
  71.             this.closePopup(null,Glydo.DetachedPopupsManager.CLOSE_REASONS.DETACHED);
  72.             this.openDetachedWindow(defs,options);
  73.         }
  74.     },
  75.  
  76.     onWindowLoaded: function(name,event) {
  77.         var win = event.currentTarget;
  78.         // The following can't work this easily, the window starts of
  79.         // with size 1. We need to track resizes if we want to do this
  80.         // properly, but only if the window was just opened
  81.         //var w = win.outerWidth;
  82.         //var h = win.outerHeight;
  83.         //var x = Math.max(win.screen.availLeft,Math.min(win.screen.availLeft + win.screen.availWidth,right)-w);
  84.         //var y = Math.max(win.screen.availTop,Math.min(win.screen.availTop + win.screen.availHeight,bottom)-h);
  85.         Glydo.Utils.addListener(win,"unload", Prototype.F.curry(this.onWindowUnloaded,name), this, false);
  86.         this.fire('onDetachedWindowOpened',name);
  87.     },
  88.     
  89.     onWindowUnloaded: function(name,event) {
  90.         delete this.detachedWindows[name];
  91.         this.fire('onDetachedWindowClosed',name);
  92.     },
  93.     
  94.     openPopup: function(defs,options) {
  95.         options = options || {};
  96.         // If a popup with another name is already open, close it.
  97.         if (this.openedPopup) {
  98.             if (defs.name == this.openedPopup.defs.name) {
  99.                 return;
  100.             }
  101.             this.closePopup(null,Glydo.DetachedPopupsManager.CLOSE_REASONS.OPENED_ANOTHER);
  102.         }
  103.         var recViewClassesMap = defs["recViewClassesMap"] || Glydo.RECOMMENDATION_VIEW_CLASSES_MAP;
  104.         var controller = new Glydo.VerticalPaneController(recViewClassesMap);
  105.         // Record and open the popup
  106.         this.openedPopup = {
  107.                 defs: defs,
  108.                 popup: this.panel,
  109.                 controller: controller,
  110.                 anchor: options.anchor,
  111.                 openTime: new Date(),
  112.                 autoHideInterval: options.auto_hide,
  113.                 autoHideTimer: null
  114.         };
  115.         position = options.position || "before_start";
  116.         // Fix position if overflowing browser window on the right,
  117.         // to reduce the effect of the firefox bug that ignores the 
  118.         // available screen area when opening non-auto-hide popups
  119.         var excess = 0;
  120.         if (options.anchor && options.ensureContainedWidth) {
  121.             // FIXME: Make this work regardless of the position used
  122.             excess = options.ensureContainedWidth - window.innerWidth + options.anchor.boxObject.x;
  123.             excess = (excess > 0) ? excess : 0; 
  124.         }
  125.         var contentsType = (defs.contentsType || defs.name);
  126.         Prototype.E.addClassName(this.panel,"glydo-vertical-pane-"+defs.name);
  127.         Prototype.E.addClassName(this.panel,"glydo-vertical-pane-contains-"+ contentsType);
  128.         if (options.realEstateKind) {
  129.             this.panel.setAttribute("realEstateKind",options.realEstateKind);
  130.         }
  131.         this.panelTitle.setAttribute("value",defs.title);
  132.         // Initialize the controller
  133.         controller.init("recpopup",this.application,defs.filter,defs.adFilter,defs.name);
  134.         controller.addListener(this);
  135.         this.panel.openPopup(options.anchor,position,-excess,-3);
  136.         this.panel.addEventListener('mouseover',this.onPanelHoverEnter,false);
  137.         this.panel.addEventListener('mouseout',this.onPanelHoverExit,false);
  138.         var tags = ({
  139.             type: "popup",
  140.             name: defs.name,
  141.             contains: contentsType
  142.         });
  143.         Glydo.LOGGING_DB.logUserEvent(
  144.                 "recommendations_pane",
  145.                 "open", tags, null);
  146.         this.startAutoHideTimerIfNecessary();
  147.     },
  148.     
  149.     startAutoHideTimerIfNecessary: function() {
  150.         if (this.openedPopup && this.openedPopup.autoHideInterval && !this.openedPopup.autoHideTimer) {
  151.             this.openedPopup.autoHideTimer = setTimeout(Prototype.F.bind(Prototype.F.curry(this.closePopup,this.openedPopup.defs.name,Glydo.DetachedPopupsManager.CLOSE_REASONS.AUTO_HIDE),this),this.openedPopup.autoHideInterval);
  152.         }
  153.     },
  154.     
  155.     stopAutoHideTimerIfNecessary: function() {
  156.         if (this.openedPopup && this.openedPopup.autoHideTimer) {
  157.             clearTimeout(this.openedPopup.autoHideTimer);
  158.             this.openedPopup.autoHideTimer = null;
  159.         }
  160.     },
  161.  
  162.     onPanelHover: function(enter,event) {
  163.         if (!this.openedPopup) {
  164.             return;
  165.         }
  166.         if (enter) {
  167.             if (this.openedPopup.hover) {
  168.                 return;
  169.             }
  170.         } else {
  171.             if (event.relatedTarget !== null) {
  172.                 if (Prototype.E.descendantOf(event.relatedTarget,this.openedPopup.popup)) {
  173.                     return;
  174.                 }
  175.             }
  176.             if (!this.openedPopup.hover) { 
  177.                     return;
  178.             }
  179.         }
  180.         this.openedPopup.hover = !this.openedPopup.hover;
  181.         if (this.openedPopup.hover) {
  182.             this.stopAutoHideTimerIfNecessary();
  183.         } else {
  184.             this.startAutoHideTimerIfNecessary();
  185.         }
  186.     },
  187.  
  188.     closePopup: function(name,reason) {
  189.         if (!this.openedPopup) {
  190.             return;
  191.         }
  192.         if (!name || (this.openedPopup.defs.name == name)) {
  193.             // We need to destroy the controller
  194.             this.openedPopup.controller.destroy();
  195.             this.openedPopup.hideReason = reason;
  196.             this.openedPopup.popup.hidePopup();
  197.         }
  198.     },
  199.     
  200.     togglePopup: function(defs,options) {
  201.         if (!this.openedPopup) {
  202.             this.openPopup(defs,options);
  203.             return true;
  204.         } else {
  205.             if (this.openedPopup.defs.name == defs.name) {
  206.                 this.closePopup(null,Glydo.DetachedPopupsManager.CLOSE_REASONS.USER_CLOSE);
  207.                 return false;
  208.             } else {
  209.                 this.openPopup(defs,options);
  210.                 return true;
  211.             }
  212.         }
  213.     },
  214.     
  215.     focusWindowOrTogglePopup: function(defs,options) {
  216.         var win = this.detachedWindows[defs.name];
  217.         if (win) {
  218.             win.focus();
  219.             return true;
  220.         } else {
  221.             return this.togglePopup(defs,options);
  222.         }
  223.     },
  224.     
  225.     onPopupShowing: function(event) {
  226.         if (!this.openedPopup) {
  227.             return;
  228.         }
  229.         this.fire('onPopupOpening',this.openedPopup.defs.name);
  230.     },
  231.  
  232.     onPopupShown: function(event) {
  233.         if (!this.openedPopup) {
  234.             return;
  235.         }
  236.         this.openedPopup.controller.onVisible();
  237.         this.fire('onPopupOpened',this.openedPopup.defs.name);
  238.     },
  239.  
  240.     onPopupHiding: function(event) {
  241.     },
  242.     
  243.     onPopupHidden: function(event) {
  244.         if (!this.openedPopup) {
  245.             return;
  246.         }
  247.         if (this.openedPopup.autoHideTimer) {
  248.             clearTimeout(this.openedPopup.autoHideTimer);
  249.         }
  250.         var name = this.openedPopup.defs.name;
  251.         var reason = this.openedPopup.hideReason;
  252.         var openTime = this.openedPopup.openTime;
  253.         var contentsType = this.openedPopup.defs.contentsType;
  254.         contentsType = contentsType || name;
  255.         Prototype.E.removeClassName(this.panel,"glydo-vertical-pane-"+name);
  256.         Prototype.E.removeClassName(this.panel,"glydo-vertical-pane-contains-"+ contentsType);
  257.         this.panel.removeAttribute("realEstateKind");
  258.         this.panelTitle.removeAttribute("value");
  259.         this.openedPopup = null;
  260.         this.fire('onPopupClosed',name,reason,(new Date().getTime()) - openTime.getTime());
  261.         var tags = ({
  262.             type: "popup",
  263.             name: name,
  264.             contains: contentsType
  265.         });
  266.         if (reason && reason.name) {
  267.             tags.reason = reason.name;
  268.         }
  269.         Glydo.LOGGING_DB.logUserEvent(
  270.                 "recommendations_pane",
  271.                 "close", tags,
  272.                 (new Date().getTime()) - openTime.getTime());
  273.     },
  274.  
  275.     detachPopup: function() {
  276.         if (!this.openedPopup) {
  277.             return;
  278.         }
  279.         var defs = this.openedPopup.defs;
  280.         var anchor = this.openedPopup.anchor;
  281.         this.openDetachedWindow(defs,anchor,this.openedPopup.popup);
  282.         this.closePopup(null,Glydo.DetachedPopupsManager.CLOSE_REASONS.DETACHED);
  283.     },
  284.     
  285.     onCurrentBrowserChanged: function(browser) {
  286.         this.closePopup(null,Glydo.DetachedPopupsManager.CLOSE_REASONS.CHANGED_CONTEXT);
  287.     },
  288.     
  289.     getContextRecommendation: function() {
  290.         if (this.openedPopup) {
  291.             return this.openedPopup.controller.getContextRecommendation();
  292.         }
  293.     },
  294.     
  295.     onContextMenu: function(event) {
  296.         if (this.openedPopup) {
  297.             return this.openedPopup.controller.onContextMenu(event);
  298.         }
  299.         return true;
  300.     },
  301.     
  302.     isPopupOpen: function() {
  303.         return !!this.openedPopup;
  304.     },
  305.  
  306.     onCurrentProcessedDocumentChanged: function(docEntry) {
  307.         this.closePopup(null,Glydo.DetachedPopupsManager.CLOSE_REASONS.CONTEXT_CHANGE);
  308.     },
  309.     
  310.     onPopupCloseButtonClick: function() {
  311.         var tags = ({
  312.             type: "popup",
  313.         });
  314.         if (this.openedPopup) {
  315.             var defs = this.openedPopup.defs;
  316.             tags.name = defs.name;
  317.             tags.contains = defs.contentsType || defs.name;
  318.         }
  319.         Glydo.LOGGING_DB.logUserEvent(
  320.                 "recommendations_pane.buttons.close",
  321.                 "click", tags,
  322.                 (new Date().getTime()) - this.openedPopup.openTime.getTime());
  323.         this.closePopup(null,Glydo.DetachedPopupsManager.CLOSE_REASONS.USER_CLOSE)
  324.     }
  325. });
  326.  
  327. Glydo.DetachedPopupsManager.CLOSE_REASONS = ({
  328.     USER_CLOSE: {
  329.         name: "user_close",
  330.         interaction: true
  331.     },
  332.     OPENED_ANOTHER: {
  333.         name: "opened_another",
  334.         interaction: true
  335.     },
  336.     DETACHED: {
  337.         name: "detached",
  338.         interaction: true
  339.     },
  340.     DOCKED: {
  341.         name: "docked",
  342.         interaction: true
  343.     },
  344.     AUTO_HIDE: {
  345.         name: "auto_hide",
  346.         interaction: false
  347.     },
  348.     CONTEXT_CHANGE: {
  349.         name: "context_change",
  350.         interaction: false
  351.     }
  352. });
  353.